<?php
/**
 * Orain 模板引擎类
 *	@author lan7
 */
class tpl extends base{
	var $val = array();
	var $tplfile = null;
	var $outdir = null;
	var $cachefile = null;
	var $strhtml = null;
	var $cachetime = 0;
	var $rule = array();
	var $mkhtml = false;
	var $html_url = null;
	var $html_path = null;
	var $cache_id = null;
	var $cache = false;
	/**
	 * 构造方法
	 *
	 * @param unknown_type $sourcefile
	 * @param unknown_type $outdir
	 * @param unknown_type $cachetime
	 */
	function __construct($outdir,$cachetime=0,$mk,$cache){
		$this->cachetime = $cachetime;
		$this->outdir = $outdir;
		$this->mkhtml = $mk;
		$this->cache = $cache;
	}
	/**
	 * 模板赋值
	 *
	 * @param unknown_type $k
	 * @param unknown_type $v
	 */
	function assign($k,$v){
		$this->val[$k] = $v;
	}
	/**
	 * 检查缓存数据是否可用
	 *
	 * @param unknown_type $id
	 * @return unknown
	 */
	function isCached($id){
		$this->cache_id = $id;
		return cache::isCached("tpl",$id);
	}
	/**
	 * 输出模板
	 *
	 * @param unknown_type $tplfile
	 */
	function display($tplfile){
		/** 支持页面级缓存 **/
		$this->cache = $this->cache?($GLOBALS['__page_cache__']?true:false):false;
		$htmlcontent = $this->fetch($tplfile,$GLOBALS["ora_cfg"]["charset"],'text/html',false);
		if($GLOBALS["ora_cfg"]["mk_html"]&&!in_array($GLOBALS['mod'],$GLOBALS["ora_cfg"]["mod_array"])){
			$this->mkhtml($this->html_path,$htmlcontent);
		}
		echo($htmlcontent);
		exit();
	}
	function mkhtml($html_path,&$htmlcontent){
		io::write($html_path,$htmlcontent);
	}
	function fetch($tplfile,$charset,$contentType='text/html',$display=false){
		$this->tplname = $tplfile;
		$this->tplfile = TPL_PATH.$tplfile;
		$this->cachefile = $this->outdir.md5($tplfile).".cache.php";
		$this->html_url  = get_html_url(true);
		$this->html_path = get_html_path();
		if(!file_exists($this->tplfile)){
			throwException("模板文件不存在:$this->tplfile",__FILE__,__LINE__,"");
		}
		if(empty($charset)){
			$charset = $GLOBALS["ora_cfg"]['charset'];
		}
		if($this->cache){
			if(!cache::isCached("tpl",$this->cache_id)){
				/**缓存过期,重新写入缓存**/
				cache::write("tpl",$this->cache_id,$this->val);
			}else{
				/** 缓存可用 **/
				if(!empty($this->cache_id)){
					$tempData = cache::read("tpl",$this->cache_id);
					if(is_array($tempData)){
						$this->val = array_merge($tempData,$this->val);
					}
				}
			}
		}
		ob_start();
		ob_implicit_flush(0);
		header("Content-Type:".$contentType."; charset=".$charset);
		header("Cache-control: private");
		extract($this->val);
		if(!$this->chkCache()){
			$this->compile();
		}
		include_once($this->cachefile);
		$content = ob_get_clean();
		if(!$display){
			return $content;
		}
		echo($content);
		return null;
	}
	/**
	 * 加载模板规则
	 *
	 */
	function loadRule($rulefile=null){
		if(empty($this->rule)){
			if (empty($rulefile)){
				$rulefile = ROOT_PATH."config/tpl.config.php";
			}
			$this->rule = include($rulefile);
		}
	}
	/**
	 * 编译模板
	 *
	 */
	function compile(){
		$this->rule = include(ROOT_PATH."config/tpl.config.php");
		$html = io::read($this->tplfile);
		$pat = '/(\<!\-\-)?'.$GLOBALS["ora_cfg"]["tag_prefix"].'\s*?include\s+(.*?)\s*?'.$GLOBALS["ora_cfg"]["tag_suffix"].'(\-\-\>)?/i';
		preg_match_all ($pat,$html,$fArr, PREG_PATTERN_ORDER);
		for($j=0;$j<sizeof($fArr[2]);$j++){
			$f = TPL_PATH.$fArr[2][$j];
			if(!file_exists($f)){
				throwException("模板文件不存在: ".$f,__FILE__,__LINE__);
			}
			$s = str_replace('/','\/',str_replace('\\','/',$fArr[2][$j]));
			//处理include 语句
			$tmps='/(\<!\-\-)?'.$GLOBALS["ora_cfg"]["tag_prefix"].'\s*?include\s+'.$s.'\s*?'.$GLOBALS["ora_cfg"]["tag_suffix"].'(\-\-\>)?/i';
			$html = preg_replace($tmps,io::read($f),$html);
		}
		@$html = preg_replace($this->rule[0],$this->rule[1],$html);
		io::write($this->cachefile,$html);
	}

	/**
	 * 检查缓存是否可用
	 *
	 * @return unknown
	 */
	function chkCache(){
		if ($GLOBALS["ora_cfg"]['cache_time']=='0'){//默认缓存关闭
			return false;
		}else if(!is_file($this->cachefile)){
			return false;
		}else if($GLOBALS["ora_cfg"]['cache_time'] < 0){//永久性开启缓存
			//缓存可用
			return true;
		}elseif (filemtime($this->tplfile) > filemtime($this->cachefile)) {
			// 模板文件有更新
			return false;
		}elseif ($GLOBALS["ora_cfg"]['cache_time'] > 0 && time() > filemtime($this->cachefile)+$GLOBALS["ora_cfg"]['cache_time']){
			// 缓存是否在有效期
			return false;
		}
		return true;
	}
}

?>